{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "887ae6fb",
   "metadata": {},
   "source": [
    "(nuclio-real-time-functions)=\n",
    "# Nuclio real-time functions\n",
    "\n",
    "Nuclio is a high-performance \"serverless\" framework focused on data, I/O, and compute intensive workloads. It is well integrated with popular \n",
    "data science tools, such as Jupyter and Kubeflow; supports a variety of data and streaming sources; and supports execution over CPUs and GPUs. \n",
    "\n",
    "You can use Nuclio through a fully managed application service (in the cloud or on-prem) in the Iguazio MLOps Platform. MLRun serving \n",
    "utilizes serverless Nuclio functions to create multi-stage real-time pipelines. \n",
    "\n",
    "The underlying Nuclio serverless engine uses a high-performance parallel processing engine that maximizes the utilization of CPUs and GPUs, \n",
    "supports 13 protocols and invocation methods (for example, HTTP, Cron, Kafka, Kinesis), and includes dynamic auto-scaling for HTTP and \n",
    "streaming. Nuclio and MLRun support the full life cycle, including auto-generation of micro-services, APIs, load-balancing, logging, \n",
    "monitoring, and configuration management—such that developers can focus on code, and deploy to production faster with minimal work.\n",
    "\n",
    "Nuclio is extremely fast: a single function instance can process hundreds of thousands of HTTP requests or data records per second. To learn \n",
    "more about how Nuclio works, see the Nuclio architecture [documentation](https://nuclio.io/docs/latest/concepts/architecture/). \n",
    "\n",
    "Nuclio is secure: Nuclio is integrated with Kaniko to allow a secure and production-ready way of building Docker images at run time.\n",
    "\n",
    "Read more in the [Nuclio documentation](https://nuclio.io/docs/latest/) and the open-source [MLRun library](https://github.com/mlrun/mlrun).\n",
    "\n",
    "## Example of Nuclio function\n",
    "\n",
    "You can create your own Nuclio function, for example a data processing function. For every Nuclio function, by default, there is one worker. See [Number of GPUs](../runtimes/configuring-job-resources.html#number-of-gpus).\n",
    "\n",
    "The following code illustrates an example of an MLRun function, of kind 'nuclio', that can be deployed to the cluster."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c9b59b3",
   "metadata": {},
   "source": [
    "Create a file `func.py` with the code of the function: \n",
    "```\n",
    "def handler(context, event):\n",
    "    return \"Hello\"\n",
    "```    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2dcd26e",
   "metadata": {},
   "source": [
    "Create the project and the Nuclio function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "105fb38e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import mlrun"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc620518",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the project\n",
    "project = mlrun.get_or_create_project(\"nuclio-project\", \"./\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5dda40ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a Nuclio function\n",
    "project.set_function(\n",
    "    func=\"func.py\",\n",
    "    image=\"mlrun/mlrun\",\n",
    "    kind=\"nuclio\",\n",
    "    name=\"nuclio-func\",\n",
    "    handler=\"handler\",\n",
    ")\n",
    "# Save the function within the project\n",
    "project.save()\n",
    "# Deploy the function in the cluster\n",
    "project.deploy_function(\"nuclio-func\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff7c7a91",
   "metadata": {},
   "source": [
    "## Nuclio API gateway\n",
    "This example demonstrates making an HTTP request to an HTTPS API Gateway of a Nuclio function using basic/access key authentication."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d983231",
   "metadata": {},
   "outputs": [],
   "source": [
    "import mlrun\n",
    "import nuclio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38fbc82c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a project\n",
    "project = mlrun.get_or_create_project(\n",
    "    \"nuclio-api-gateway-example\", context=\"./\", user_project=True\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1199cf14",
   "metadata": {},
   "outputs": [],
   "source": [
    "# mlrun: start-code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50143d4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def handler(context, event):\n",
    "    return \"test\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b7449b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# mlrun: end-code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2019278",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a simple Nuclio function that gets basic authentication\n",
    "basic_auth = project.set_function(\n",
    "    name=\"basic-auth\", handler=\"handler\", image=\"mlrun/mlrun\", kind=\"nuclio\"\n",
    ")\n",
    "# Create a simple nuclio function that gets accesss key authentication\n",
    "access_key_auth = project.set_function(\n",
    "    name=\"acces-key\", handler=\"handler\", image=\"mlrun/mlrun\", kind=\"nuclio\"\n",
    ")\n",
    "project.save()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71f61991",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Deploy the function\n",
    "basic_auth.deploy()\n",
    "access_key_auth.deploy()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c32395ec",
   "metadata": {},
   "source": [
    "### Making an HTTP request using basic authentication\n",
    "1. Create an API Gateway in the UI, with authentication `basic`. Set your desired username and password and choose the `basic-auth` nuclio function.\n",
    "2. Give it a name and copy the endpoint.\n",
    "2. Paste the endpoint after the `https://`.\n",
    "2. Change the username and password in the code below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d10a986",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "from base64 import b64encode\n",
    "\n",
    "# Authorization token: Encode to Base64 format\n",
    "# and then decode it to ASCII since python 3 stores it as a byte string\n",
    "def basic_auth(username, password):\n",
    "    token = b64encode(f\"{username}:{password}\".encode(\"utf-8\")).decode(\"ascii\")\n",
    "    return f\"Basic {token}\"\n",
    "\n",
    "\n",
    "# Enter your username and password here\n",
    "username = \"username\"\n",
    "password = \"password\"\n",
    "\n",
    "# Enter your API Gateway endpoint here\n",
    "basic_auth_api_gateway_path = \"https://<API GATEWAY ENDPOINT>\"\n",
    "\n",
    "headers = {\"Authorization\": basic_auth(username, password)}\n",
    "res = requests.get(url=basic_auth_api_gateway_path, headers=headers, verify=False)\n",
    "print(res.text)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5941683",
   "metadata": {},
   "source": [
    "### Making an HTTP request using access key authentication\n",
    "1. Create an API Gateway in the UI, with authentication `access key` and choose the `access-key` Nuclio function.\n",
    "2. Give it a name and copy the endpoint.\n",
    "2. Paste the endpoint after the `https://`.\n",
    "2. In the UI, click the user's top right icon, then copy the access key from there.\n",
    "2. Change the access key in the code below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d181272",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Enter your access key here\n",
    "access_key = \"some-access-key\"\n",
    "\n",
    "# Enter your API Gateway endpoint here\n",
    "access_key_auth_api_gateway_path = \"https://<API GATEWAY ENDPOINT>\"\n",
    "\n",
    "headers = {\"Cookie\": 'session=j:{\"sid\": \"' + access_key + '\"}'}\n",
    "res = requests.get(url=access_key_auth_api_gateway_path, headers=headers, verify=False)\n",
    "print(res.text)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
